home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Reference / the cmsp digests ('94-'97) / csmp digest Vol 3 No 017 < prev    next >
Internet Message Format  |  1997-05-06  |  74KB

  1. From: pottier@clipper.ens.fr (Francois Pottier)
  2. Subject: csmp-digest-v3-017
  3. Date: Wed, 20 Apr 94 13:09:01 MET DST
  4.  
  5. C.S.M.P. Digest             Wed, 20 Apr 94       Volume 3 : Issue 17
  6.  
  7. Today's Topics:
  8.  
  9.         'aete' and AppleScript
  10.         Help on recursive read of directory catalog..?
  11.         How can I display TIFF?
  12.         Inverting a button in a dialog
  13.         Looking for styled TE replacement?
  14.         Mounting AFPServer volume...
  15.         PPC ThreadManager w-CodeWarrior
  16.         RJW: Retrieving application name from OSType Creator
  17.         Range of OSErr's for private use?
  18.         Simple Q: Assigning char * to char []. How?
  19.         [Q] Validity of a memory address
  20.         textedit bounds
  21.  
  22.  
  23.  
  24. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  25. (pottier@clipper.ens.fr).
  26.  
  27. The digest is a collection of article threads from the internet newsgroup
  28. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  29. regularly and want an archive of the discussions.  If you don't know what a
  30. newsgroup is, you probably don't have access to it.  Ask your systems
  31. administrator(s) for details.  If you don't have access to news, you may
  32. still be able to post messages to the group by using a mail server like
  33. anon.penet.fi (mail help@anon.penet.fi for more information).
  34.  
  35. Each issue of the digest contains one or more sets of articles (called
  36. threads), with each set corresponding to a 'discussion' of a particular
  37. subject.  The articles are not edited; all articles included in this digest
  38. are in their original posted form (as received by our news server at
  39. nef.ens.fr).  Article threads are not added to the digest until the last
  40. article added to the thread is at least two weeks old (this is to ensure that
  41. the thread is dead before adding it to the digest).  Article threads that
  42. consist of only one message are generally not included in the digest.
  43.  
  44. The digest is officially distributed by two means, by email and ftp.
  45.  
  46. If you want to receive the digest by mail, send email to listserv@ens.fr
  47. with no subject and one of the following commands as body:
  48.     help                        Sends you a summary of commands
  49.     subscribe csmp-digest Your Name    Adds you to the mailing list
  50.     signoff csmp-digest            Removes you from the list
  51. Once you have subscribed, you will automatically receive each new
  52. issue as it is created.
  53.  
  54. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  55. Questions related to the ftp site should be directed to
  56. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  57. digest are available there.
  58.  
  59. Also, the digests are available to WAIS users as comp.sys.mac.programmer.src.
  60.  
  61.  
  62. -------------------------------------------------------
  63.  
  64. >From "Jared M. Oberhaus" <oberhaus+@CMU.EDU>
  65. Subject: 'aete' and AppleScript
  66. Date: Tue, 29 Mar 1994 03:54:34 -0500
  67. Organization: Senior, Electrical and Computer Engineering, Carnegie Mellon, Pittsburgh, PA
  68.  
  69. OK, I think I've figured out that the aete resource is the Dictionary
  70. for translating raw AppleEvent formats into plain English-like commands.
  71.  
  72. But, where is the Template resource for ResEdit, so I can create and
  73. modify this resource?
  74.  
  75. And if it doesn't exist yet, how do all you other guys do it? Not the
  76. hard way, I hope...
  77.  
  78. Help!!
  79.  
  80. ps-I saw the demo of Resorcerer and noticed that it supports aete
  81. resources, and looked around, and I supposed I could figure out how to
  82. do an aete resoure by looking at the hex offsets, etc., but I don't
  83. exactly feel like doing that!
  84.  
  85. pps-If you could, when you respond, could you respond to All (that is,
  86. put me on the adressee list) instead of just Readers, that way, it'll be
  87. easier than looking through five hundred messages every day... Thanks!
  88.  
  89.  
  90. - ---------------------------------------------------------------------------
  91. Jared M. Oberhaus                                           oberhaus+@CMU.EDU
  92. Electrical and Computer Engineering                             Class of 1994
  93. Carnegie Mellon University
  94. - ---------------------------------------------------------------------------
  95. "We are upping our standards,...so up yours."  
  96.         - Pat Paulsen for President, 1988
  97.  
  98.  
  99. +++++++++++++++++++++++++++
  100.  
  101. >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
  102. Date: 30 Mar 94 11:19:56 +1300
  103. Organization: University of Waikato, Hamilton, New Zealand
  104.  
  105. In article <AhZyn_y00iV4E0fEpd@andrew.cmu.edu>, "Jared M. Oberhaus" <oberhaus+@CMU.EDU> writes:
  106. > OK, I think I've figured out that the aete resource is the Dictionary
  107. > for translating raw AppleEvent formats into plain English-like commands.
  108. >
  109. > But, where is the Template resource for ResEdit, so I can create and
  110. > modify this resource?
  111.  
  112. I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
  113. doesn't seem to be entirely reliable in its support for templates, and I've
  114. hit problems trying to use it to open some aete resources.
  115.  
  116. Generally, if I want to know details of event IDs etc, I use MPW's DeRez to
  117. decompile the aete into source form. If I don't, then the Script Editor's
  118. "Open Dictionary" command suffices.
  119.  
  120. Lawrence D'Oliveiro                       fone: +64-7-856-2889
  121. Info & Tech Services Division              fax: +64-7-838-4066
  122. University of Waikato            electric mail: ldo@waikato.ac.nz
  123. Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
  124. My hard disk is a Mightgrosoft-free zone.
  125.  
  126. +++++++++++++++++++++++++++
  127.  
  128. >From knut.mork@admin.uio.no (Knut Mork)
  129. Date: Wed, 30 Mar 1994 10:16:28 +0200
  130. Organization: UniNett
  131.  
  132. In article <1994Mar30.111959.27070@waikato.ac.nz>, ldo@waikato.ac.nz
  133. (Lawrence D'Oliveiro, Waikato University) wrote:
  134.  
  135. > In article <AhZyn_y00iV4E0fEpd@andrew.cmu.edu>, "Jared M. Oberhaus" <oberhaus+@CMU.EDU> writes:
  136. > > OK, I think I've figured out that the aete resource is the Dictionary
  137. > > for translating raw AppleEvent formats into plain English-like commands.
  138. > >
  139. > > But, where is the Template resource for ResEdit, so I can create and
  140. > > modify this resource?
  141. > I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
  142. > doesn't seem to be entirely reliable in its support for templates, and I've
  143. > hit problems trying to use it to open some aete resources.
  144. > Generally, if I want to know details of event IDs etc, I use MPW's DeRez to
  145. > decompile the aete into source form. If I don't, then the Script Editor's
  146. > "Open Dictionary" command suffices.
  147.  
  148. The AppleScript developer CD also has a HyperCard stack for constructing
  149. aete resources, which is extremely useful. It has Rez templates for MPW,
  150. but those didn't work.. they compiled 'aete' resources which were invalid,
  151. at least for me. Anybody else have this problem?
  152.  
  153. --Knut
  154.  
  155. +++++++++++++++++++++++++++
  156.  
  157. >From mlanett@netcom.com (Mark Lanett)
  158. Date: Wed, 30 Mar 1994 08:14:12 GMT
  159. Organization: Etch-a-Sketch Analysis and Design
  160.  
  161. ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
  162.  
  163. >I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
  164. >doesn't seem to be entirely reliable in its support for templates, and I've
  165. >hit problems trying to use it to open some aete resources.
  166.  
  167. I don't have the AS toolkit, so when I felt like doing stuff with scripting
  168. I had to figure out the format of the aete resource myself, and...
  169. It looks like it can't be handled by ResEdit. Apparently all the "direct"
  170. types like shorts and longs are word-aligned, but strings are not. There's no
  171. way to create a template which handles word-alignment in ResEdit, alas, and
  172. since the strings *aren't* aligned you can't make a template that works by
  173. specifying ESTR instead of PSTR.
  174.  
  175. >...the Script Editor's
  176. >"Open Dictionary" command suffices.
  177.  
  178. Never even thought of that one. Oh well, Sucks to be me.
  179.  
  180. >My hard disk is a Mightgrosoft-free zone.
  181. I love MS products. *My* HD is a Symantec-free zone.
  182. -- 
  183.     Mark Lanett "...a bajillion brilliant Jobsian lithium licks"
  184.  
  185. +++++++++++++++++++++++++++
  186.  
  187. >From alldritt@mdd.comm.mot.com (Mark Alldritt)
  188. Date: 30 Mar 1994 08:31:00 -0800
  189. Organization: Motorola - Wireless Data Group; Richmond, BC
  190.  
  191. In <mlanettCnGxJo.Fov@netcom.com> mlanett@netcom.com (Mark Lanett) writes:
  192.  
  193. >ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
  194.  
  195. >>I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
  196. >>doesn't seem to be entirely reliable in its support for templates, and I've
  197. >>hit problems trying to use it to open some aete resources.
  198.  
  199. >I don't have the AS toolkit, so when I felt like doing stuff with scripting
  200. >I had to figure out the format of the aete resource myself, and...
  201. >It looks like it can't be handled by ResEdit. Apparently all the "direct"
  202. >types like shorts and longs are word-aligned, but strings are not. There's no
  203. >way to create a template which handles word-alignment in ResEdit, alas, and
  204. >since the strings *aren't* aligned you can't make a template that works by
  205. >specifying ESTR instead of PSTR.
  206.  
  207. The AppleScript developer CD contains a TMPL resource for editing aete
  208. resources which works reasonably well.  The problem is that TMPL layouts
  209. can only handle a limited number of fields.  Application aete resources are
  210. generally too large to be edited using the aete TMPL.
  211.  
  212. Another alternative is the aete editing Hypercard stack Apple provides on 
  213. the AppleScript CD and (I think) on the Develop Bookmark CD.
  214.  
  215. However, if your just interested in know what events and classes a application
  216. understands then the Script Editor's dictionary window is your best bet.
  217.  
  218. -Mark
  219.  
  220. +++++++++++++++++++++++++++
  221.  
  222. >From lai@apple.com (Ed Lai)
  223. Date: 5 Apr 1994 17:04:19 GMT
  224. Organization: Apple
  225.  
  226. In article <AhZyn_y00iV4E0fEpd@andrew.cmu.edu>, "Jared M. Oberhaus"
  227. <oberhaus+@CMU.EDU> wrote:
  228.  
  229. > OK, I think I've figured out that the aete resource is the Dictionary
  230. > for translating raw AppleEvent formats into plain English-like commands.
  231. > But, where is the Template resource for ResEdit, so I can create and
  232. > modify this resource?
  233.  
  234. It should be on the developer CD. You should also find a copy in
  235. from ftp.apple.com in /pub/appleevents, although that may not be the
  236. latest copy. The problem is that ResEdit template editing probably
  237. uses the dialog manager and there can only be a limited number of
  238. item in the dialog, any decent size aete would reach the limit so
  239. for practical purpose it is useless for aete unless the aete is
  240. are very simple like those in an OSAX.
  241.  
  242. You should be able to find the HyperCard aete editor stack in the 
  243. same place.
  244.  
  245. > And if it doesn't exist yet, how do all you other guys do it? Not the
  246. > hard way, I hope...
  247. > Help!!
  248. > ps-I saw the demo of Resorcerer and noticed that it supports aete
  249. > resources, and looked around, and I supposed I could figure out how to
  250. > do an aete resoure by looking at the hex offsets, etc., but I don't
  251. > exactly feel like doing that!
  252.  
  253. I hear that Resorcerer is very good at editing aete resource, this is
  254. certainly a solution for those who owns Resorcerer.
  255.  
  256. There is yet another solution. I have written an osax to translate
  257. between resources and list using ResEdit template, and since aete is 
  258. a resource with ResEdit template. In theory you can use the osax
  259. and generate aete resource using AppleScript. I have not tried it
  260. for a long time, but I suspect it is very slow so may not be
  261. practical except for smaller aete. The osax can be found in
  262. ftp.apple.com in /pub/lai/osax/pgmTool.sit.hqx
  263.  
  264. -- 
  265. /* Disclaimer: All statments and opinions expressed are my own */
  266. /* Edmund K. Lai                                               */
  267. /* Apple Computer, MS303-3A                                    */
  268. /* 20525 Mariani Ave,                                          */
  269. /* Cupertino, CA 95014                                         */
  270. /* (408)974-6272                                               */
  271. zW@h9cOi
  272.  
  273. ---------------------------
  274.  
  275. >From dsf5454@ritvax.isc.rit.edu
  276. Subject: Help on recursive read of directory catalog..?
  277. Date: Sun, 3 Apr 1994 16:59:38 GMT
  278. Organization: Rochester Institute of Technology
  279.  
  280. Ok...basically, I have a crucial subroutine where I need to read a directory
  281. tree below a specific subdirectory. However, I notice that I seem to be
  282. crashing into the debugger with an error of #28 and somewhere around in a VBL
  283. queue - stack and application heap collison. Therefore, I'm not sure how I
  284. could efficiently code such a recursive call... suggestions or pointers,
  285. anybody? I'm calling it with RecursiveDirList(1, 2L); in main to tell it to
  286. start from root folder.
  287.  
  288. I have a newer version that was re-written, but the principle is the same...
  289. Roughly speaking, here's what it looks like at the moment..:
  290.  
  291. -Dan
  292. Internet:    dsf5454@ritvax.isc.rit.edu
  293. BITNET/CREN:    dsf5454@ritvax.BITNET
  294.  
  295. long RecursiveDirList (t, dirIDToSearch)
  296. short t;
  297. long dirIDToSearch;
  298. {
  299.     short    index = 1;
  300.     OSErr    err;
  301.     long    curLine;
  302.  
  303.     do {
  304.  
  305.         myCPB.fileParam.ioFDirIndex = index;
  306.         myCPB.fileParam.ioVRefNum = vRefNum;
  307.         myCPB.fileParam.ioDirID = dirIDToSearch;
  308.         myCPB.fileParam.ioNamePtr = (unsigned char *)fName;
  309.  
  310.         err = PBGetCatInfo ((CInfoPBPtr)&myCPB, 0);
  311.         
  312.         if (err == noErr) 
  313.         {
  314.             if (((myCPB.fileParam.ioFlAttrib >> 4) & 0x01) == 1) 
  315.             {
  316.                 RecursiveDirList(t+1,myCPB.fileParam.ioDirID);
  317.                 err = 0;
  318.                 /* It's a directory; we want to go deeper into
  319.                 the subdirectories */
  320.             } 
  321.             else 
  322.             {
  323.                 /* it's a file */
  324.             }
  325.         }
  326.         index++;
  327.     } while ((err != fnfErr) && (err == noErr));
  328. }
  329.                                
  330.  
  331. +++++++++++++++++++++++++++
  332.  
  333. >From allon@intercon.com (Allon Stern)
  334. Date: Tue,  5 Apr 1994 03:09:18 -0400
  335. Organization: InterCon Systems Corporation, Herndon VA.
  336.  
  337. In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, 
  338. dsf5454@ritvax.isc.rit.edu writes:
  339. > Ok...basically, I have a crucial subroutine where I need to read a 
  340. > directory tree below a specific subdirectory. However, I notice that I 
  341. > seem to be crashing into the debugger with an error of #28 and 
  342. > somewhere around in a VBL queue - stack and application heap collison. 
  343. > Therefore, I'm not sure how I could efficiently code such a recursive 
  344. > call... suggestions or pointers, anybody? I'm calling it with 
  345. > RecursiveDirList(1, 2L); in main to tell it to start from root folder. 
  346. > I have a newer version that was re-written, but the principle is the 
  347. > same... 
  348. > Roughly speaking, here's what it looks like at the moment..: 
  349. > -Dan 
  350. > Internet:    dsf5454@ritvax.isc.rit.edu 
  351. > BITNET/CREN:    dsf5454@ritvax.BITNET 
  352.  
  353. It seems to me that you could probably do this non-recusively.
  354. Keep in mind that you will end up using stack space for each recursive call,
  355. and also that PBGetCatInfo and the file manager may also use some stack
  356. space.
  357.  
  358. Rather than using the stack to store where you were, you could build your own
  359. stack structure, say, using an array.  This would minimize stack usage, and
  360. would also store the same information much more efficiently.  If it is a
  361. transient thing (i.e. you use a bunch of storage for a short time, then would
  362. release it), you could use temporary memory for it.  You could also use a
  363. dynamic array, and if you run out of room in your own heap, you could transfer
  364. the contents to a handle in temporary memory space.
  365.  
  366. You could try increasing the memory requested for the program, but I think
  367. the best thing in this case is to find a non-recursive way to do it.
  368. --
  369. Allon
  370.  
  371.  
  372. | Allon Stern        | 703-709-5557 |  Ring around the Internet    |
  373. | allon@intercon.com |    KE4FYL    |  A packet with a bit not set |
  374. +--------------------+--------------+  ENQ ACK ENQ ACK             |
  375. |  All opinions above are my own.   |  We all go down!             |
  376. |------------------------------------------------------------------|
  377.  
  378.  
  379.  
  380. +++++++++++++++++++++++++++
  381.  
  382. >From d88-jwa@mumrik.nada.kth.se (Jon Wätte)
  383. Date: 5 Apr 1994 08:13:09 GMT
  384. Organization: The Royal Institute of Technology
  385.  
  386. In <9404050309.AA18685@hazmat.intercon.com> allon@intercon.com (Allon Stern) writes:
  387.  
  388. >> Ok...basically, I have a crucial subroutine where I need to read a 
  389. >> directory tree below a specific subdirectory. However, I notice that I 
  390. >> seem to be crashing into the debugger with an error of #28 and 
  391. >> somewhere around in a VBL queue - stack and application heap collison. 
  392.  
  393. >It seems to me that you could probably do this non-recusively.
  394. >Keep in mind that you will end up using stack space for each recursive call,
  395. >and also that PBGetCatInfo and the file manager may also use some stack
  396. >space.
  397.  
  398. Yeah, but PBGetCatInfo will give the stack space back when it's done.
  399. (It should be called as PBGetCatInfoSync() by the way, or maybe
  400. PBGetCatInfoAsync ( ) ; while ( rec . ioResult == 1 ) Yield ( ) ;)
  401.  
  402. Anyway, his routine only ate 4+4+4+4+4+4+4 bytes per recursion
  403. (2 int arguments, a6 link, return address, three int locals, given
  404. 4-byte ints)
  405. At 28 bytes per recursion, you need > 1000 folders deep structures
  406. to hit any real problems, unless you have MASSIVE parameter blocks
  407. and Str255s on the stack higher up. (Putting Str255s on the stack
  408. is a BAD idea btw)
  409.  
  410. What he could do is call StackSpace() (or whatever) before each
  411. recursive call, and call Debugger() if it goes below a K or so.
  412. Most probably, however, he's having some other bug which is causing
  413. the problem.
  414. -- 
  415.  -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
  416.  
  417.    What we need is a good GNU [...] licence manager implementation.
  418.                      -- Raphael Manfredi
  419.  
  420. +++++++++++++++++++++++++++
  421.  
  422. >From jumplong@aol.com (Jump Long)
  423. Date: 5 Apr 1994 12:44:02 -0400
  424. Organization: America Online, Inc. (1-800-827-6364)
  425.  
  426. In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, dsf5454@ritvax.isc.rit.edu
  427. writes:
  428.  
  429. > Ok...basically, I have a crucial subroutine where I need to read a directory
  430. > tree below a specific subdirectory. However, I notice that I seem to be
  431. > crashing into the debugger with an error of #28 and somewhere around in a VBL
  432. > queue - stack and application heap collison. Therefore, I'm not sure how I
  433. > could efficiently code such a recursive call... suggestions or pointers,
  434. > anybody? I'm calling it with RecursiveDirList(1, 2L); in main to tell it to
  435. > start from root folder.
  436.  
  437. You're using too much stack in your recursive routine - either that, of you
  438. don't have much stack when you start your recursive routine.
  439.  
  440. You can check the stack space before you start with the StackSpace function. 
  441. If that isn't your problem, then you might want to look at one of the recursive
  442. routines I put in DTS's MoreFiles File Manager sample code. In particular, the
  443. routines in DirectoryCopy.c show how you can use very little stack space per
  444. level in a recursive routine that enumerates a directory structure on a
  445. Macintosh disk volume.
  446.  
  447. The code in MoreFiles is based on the ideas presented in the Technical Note "
  448.  
  449. +++++++++++++++++++++++++++
  450.  
  451. >From jumplong@aol.com (Jump Long)
  452. Date: 5 Apr 1994 12:45:03 -0400
  453. Organization: America Online, Inc. (1-800-827-6364)
  454.  
  455. In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, dsf5454@ritvax.isc.rit.edu
  456. writes:
  457.  
  458. Ooops, hit the send button too soon... starting where I left off.
  459.  
  460. on ideas presented in the Technical Note "FL 31 - Searching Volumes-Solutions
  461. and Problems".
  462.  
  463. Hope that helps.
  464.  
  465. Jim Luther
  466. Apple DTS
  467.  
  468. ---------------------------
  469.  
  470. >From jbell@garnet.berkeley.edu (John E. Bell)
  471. Subject: How can I display TIFF?
  472. Date: 22 Mar 1994 11:07:24 GMT
  473. Organization: University of California, Berkeley
  474.  
  475.  
  476. How can I display a TIFF file in my program? Are there library routines
  477. somewhere?
  478.  
  479. Thanks - John E. Bell
  480.  
  481. +++++++++++++++++++++++++++
  482.  
  483. >From mssmith@afterlife.ncsc.mil (M. Scott Smith)
  484. Date: Tue, 22 Mar 1994 12:18:47 GMT
  485. Organization: The Great Beyond
  486.  
  487. In article <2mmjhc$sno@agate.berkeley.edu> jbell@garnet.berkeley.edu (John E. Bell) writes:
  488. >
  489. >How can I display a TIFF file in my program? Are there library routines
  490. >somewhere?
  491. >
  492. >Thanks - John E. Bell
  493.  
  494. John,
  495.  
  496.    There are some samples floating about that show how to read the TIFF
  497. format.  The TIFF format is kind of an ugly thing to read; it takes a lot
  498. of work.  It's designed to be a very flexible file format, so each TIFF
  499. file starts out with a number of "tags" which can contain everything from
  500. the expected width and height of the image, to the resolution, even comments
  501. and tags/fields which are specific to certain applications.
  502.  
  503.    I guess in order to claim that your program can read TIFF, you need to
  504. intelligently read a certain number of these tags, and you can ignore the
  505. rest.
  506.  
  507.    The tags will give you information like offsets for finding the actual
  508. data, etc.
  509.  
  510.    Really kind of yechy.  But, alas: if I remember correctly, NIH Image,
  511. a program which you can find at the usual FTP sites, reads color TIFF
  512. images.  The only problem is that it's written in Pascal.  (That may
  513. not be a problem for some people.)  You can probably easily translate it
  514. to C.
  515.  
  516.    I've written black and white TIFF-reading code (not color), and I
  517. suppose I might some day spruce that up to serve as an example.  (Right now,
  518. I think I'd be embarassed to claim credit for it.  It does read files
  519. quickly though.)
  520.  
  521.    What I'd like is a nice C++ library that lets you save/read PixMaps
  522. to/from a multitude of file formats, such as PICT, TIFF, PostScript,
  523. and the like.  I don't think such a thing exists (anyone know??), so
  524. it seems whenever you want to write a program with these capabilities,
  525. you need to re-invent the wheel.
  526.  
  527.    Maybe people could get together and build this library; between us,
  528. I'm sure we have all of the capability.
  529.  
  530. Anyway, good luck with the TIFF reading.  (Trivia: TIFF stands for
  531. Tagged Image File Format.)
  532.  
  533. - Scott
  534.  
  535. - -
  536. M. Scott Smith   (mssmith@afterlife.ncsc.mil || umsmith@mcs.drexel.edu)
  537.  
  538.   Mac developer. Student.  Not a member of the Michael Bolton fan club.
  539.  
  540.  
  541. +++++++++++++++++++++++++++
  542.  
  543. >From perm@csd.uu.se (Per Mildner)
  544. Date: 22 Mar 1994 16:04:36 GMT
  545. Organization: Computing Science Dept.,Uppsala University, Sweden
  546.  
  547. I recommend looking for LIBTIFF with Archie, it reads and writes
  548. various tiff formats.  My only problem with that is that I know an
  549. application (Optix by Blueridge) that unpacks CCITT Group IV (fax)
  550. very much faster than the seemingly optimized LIBTIFF code (on a
  551. Quadra 700).
  552. Regards,
  553. --
  554. Per Mildner            Per.Mildner@CSD.UU.SE
  555. Computing Science Dept.        tel: +46 18 181049
  556. Uppsala University, Sweden    fax: +46 18 511925
  557.  
  558.  
  559. +++++++++++++++++++++++++++
  560.  
  561. >From markhanrek@aol.com (MarkHanrek)
  562. Date: 22 Mar 1994 20:45:07 -0500
  563. Organization: America Online, Inc. (1-800-827-6364)
  564.  
  565. Yes, there is some TIFF source code available from a variety of places.
  566.  
  567. The place to start, though, is the Aldus Developer Desk, which is on
  568. CompuServe, from which you will be able to download the current TIFF Level 6.0
  569. specification, example source code (for level 5), and some TIFF pictures which
  570. are good to use for testing.
  571.  
  572. Or you could contact Aldus directly. Perhaps there is Internet access to them
  573.  
  574. Mark Hanrek
  575.  
  576.  
  577. +++++++++++++++++++++++++++
  578.  
  579. >From kenlong@netcom.com (Ken Long)
  580. Date: Wed, 23 Mar 1994 02:51:35 GMT
  581. Organization: NETCOM On-line Communication Services (408 241-9760 guest)
  582.  
  583. There's some TIFF reader code on AOL.  Next time I log on I'll get a 
  584. description of it for you.  Seems like I saw some elsewhere, too.  i'll 
  585. check it out.
  586.  
  587. -Ken-
  588.  
  589. +++++++++++++++++++++++++++
  590.  
  591. >From xinwei@otter.Stanford.EDU (Sha Xin Wei)
  592. Date: 5 Apr 1994 21:39:26 GMT
  593. Organization: Stanford University
  594.  
  595. M. Scott Smith writes
  596. > In article <2mmjhc$sno@agate.berkeley.edu> jbell@garnet.berkeley.edu (John E.  
  597. Bell) writes:
  598. > >
  599. > >How can I display a TIFF file in my program? Are there library routines
  600. > >somewhere?
  601. > >
  602. > >Thanks - John E. Bell
  603. > John,
  604. >    There are some samples floating about that show how to read the TIFF
  605. > format.>    Maybe people could get together and build this library; between  
  606. us,
  607. > I'm sure we have all of the capability.
  608. > Anyway, good luck with the TIFF reading.  (Trivia: TIFF stands for
  609. > Tagged Image File Format.)
  610. > - Scott
  611. > ---
  612. > M. Scott Smith   (mssmith@afterlife.ncsc.mil || umsmith@mcs.drexel.edu)
  613.  
  614.  
  615. By the way, in the unix world there's a whole wonderful library named pbmplus  
  616. by Jef Pozkaner, written in C, which is in the public domain.  It provides a  
  617. slew of tools for conversion between 12-40 different graphics formats  
  618. (depending on how you count) -- PICT, TIFF, PS, GIF, etc., and much more: color  
  619. histogram, diffusion, quatization, scaling, rotation, palette remaps, even  
  620. general convolution given a user-supplied kernel.   All in public domain.    
  621. PixelMagician, a NeXTSTEP application has extended pbmplus to handle pixmaps  
  622. with alpha channel, and a few more formats.
  623.  
  624. If anyone has compiled this under MPW or ThinkC, could they please publish it?
  625. Thanks.
  626.  
  627. Sha Xin Wei
  628. Stanford University
  629.  
  630. ---------------------------
  631.  
  632. >From Vik_Rubenfeld@lamg.com (Vik Rubenfeld)
  633. Subject: Inverting a button in a dialog
  634. Date: 05 Apr 1994 00:21:14 -0000
  635. Organization: (none)
  636.  
  637. I've set up a filter procedure that returns the item number of the cancel
  638. button if the user hits the escape key. This lets the user dismiss the dialog
  639. from the keyboard, without using the mouse. It works great. However, it does
  640. not invert the cancel button before dismissing the dialog.
  641.  
  642. So, could someone upload some sample code that highlights (inverses) a
  643. standard dialog button? Thanks.
  644.  
  645. +++++++++++++++++++++++++++
  646.  
  647. >From t-gaul@i-link.com (Troy Gaul)
  648. Date: Tue, 05 Apr 1994 10:48:58 -0500
  649. Organization: I-Link, Ltd.
  650.  
  651. In article <101974014.48568985@lamgnet.lamg.com>, Vik_Rubenfeld@lamg.com
  652. (Vik Rubenfeld) wrote:
  653.  
  654. > I've set up a filter procedure that returns the item number of the cancel
  655. > button if the user hits the escape key. This lets the user dismiss the dialog
  656. > from the keyboard, without using the mouse. It works great. However, it does
  657. > not invert the cancel button before dismissing the dialog.
  658. > So, could someone upload some sample code that highlights (inverses) a
  659. > standard dialog button? Thanks.
  660.  
  661. ControlHandle
  662. GetControlItemHandle(DialogPtr dlog, short item) {
  663.   short  iKind;
  664.   Handle iHandle;
  665.   Rect   iRect;
  666.  
  667.   GetDItem(dlog, item, &iKind, &iHandle, &iRect);
  668.   switch (iKind & ~itemDisable) {
  669.     case btnCtrl + ctrlItem:
  670.     case chkCtrl + ctrlItem:
  671.     case radCtrl + ctrlItem:
  672.     case resCtrl + ctrlItem:
  673.       return (ControlHandle) iHandle;
  674.   }
  675.   return nil;
  676. }
  677.  
  678. void 
  679. FlashDItem(DialogPtr dlog, short item) {
  680.   long ignored;
  681.   ControlHandle button;
  682.     
  683.   button = GetControlItemHandle(dlog, item);
  684.   if (button != nil && (**button).contrlHilite != 255) {
  685.     HiliteControl(button, 1);
  686.     Delay(8, &ignored);          // the Apple prescribed period of time
  687.     HiliteControl(button, 0);
  688.   }
  689. }
  690.  
  691. Of course, to flash the cancel button, you just call:
  692.  
  693.   FlashDItem(dlog, cancel);
  694.  
  695. _troy
  696. //////// //////___Troy Gaul_________________________t-gaul@i-link.com__ //
  697.   //    //       I-Link, Ltd. ; West Des Moines, Iowa                  //
  698.  //    //  //   "Iungo ergo sum." (I-Link, therefore I am.)           //
  699. //    //////________________________________________________________ //
  700.  
  701. +++++++++++++++++++++++++++
  702.  
  703. >From charlesworth@andyne.on.ca (Dave Charlesworth)
  704. Date: Tue, 5 Apr 1994 22:15:45 GMT
  705. Organization: Andyne Computing
  706.  
  707. I don't have sample code handy but you'll find it really simple to
  708. write.  Here's the basic outline:
  709. 1.  Get the Cancel button item from the dialog.
  710. 2.  Coerce it to a control.
  711. 3.  Tell the control to highlight.
  712. 4.  Wait long enough for the user to see it.
  713. 5.  Go on with dismissing your dialog...
  714.  
  715. .../dave   Dave Charlesworth
  716.  
  717. ---------------------------
  718.  
  719. >From RobTerrell@aol.com (Rob Terrell)
  720. Subject: Looking for styled TE replacement?
  721. Date: 4 Apr 1994 17:55:08 GMT
  722. Organization: Jecta Development Corp.
  723.  
  724. A few weeks back someone mentioned a styled text edit replacement
  725. called "WASTE". The poster claimed it would do styles as well as >32K
  726. of text.
  727.  
  728. I've never heard of it, nor has archie. Any ideas?
  729.  
  730. Thanks,
  731.  
  732.  
  733. Rob
  734. Software Designs Unlimited
  735.  
  736.  
  737.  
  738. +++++++++++++++++++++++++++
  739.  
  740. >From mlanett@netcom.com (Mark Lanett)
  741. Date: Tue, 5 Apr 1994 02:30:27 GMT
  742. Organization: Etch-a-Sketch Analysis and Design
  743.  
  744. RobTerrell@aol.com (Rob Terrell) writes:
  745.  
  746. >A few weeks back someone mentioned a styled text edit replacement
  747. >called "WASTE". The poster claimed it would do styles as well as >32K
  748. >of text.
  749.  
  750. Host: ghost.dsi.unimi.it (149.132.1.2)
  751. Path: pub2/papers/piovanel/
  752. -- 
  753.     Mark Lanett "...a bajillion brilliant Jobsian lithium licks"
  754.  
  755. ---------------------------
  756.  
  757. >From rdm4@acpub.duke.edu (RYAN MARTELL)
  758. Subject: Mounting AFPServer volume...
  759. Date: 5 Apr 1994 21:26:42 GMT
  760. Organization: Duke University, Durham, N.C.
  761.  
  762.  
  763. Does anyone have any sample code showing how to mount a volume from an
  764. AFPServer remotely?  I already have the address of the Server, and
  765. figure I need to use AFPCommand, but I don't know how to send the
  766. proper name/password verification data- or is there just a standard
  767. call to do all of that for you? (Essentially, I am trying to write
  768. something that acts as the chooser for you..)
  769.  
  770. Any help would be appreciated, please reply by email.
  771.  
  772. -Ryan Martell
  773.  
  774. +++++++++++++++++++++++++++
  775.  
  776. >From jumplong@aol.com (Jump Long)
  777. Date: 5 Apr 1994 23:55:02 -0400
  778. Organization: America Online, Inc. (1-800-827-6364)
  779.  
  780. In article <2nsl2i$p38@news.duke.edu>, rdm4@acpub.duke.edu (RYAN MARTELL)
  781. writes:
  782.  
  783. > Does anyone have any sample code showing how to mount a volume from an
  784. > AFPServer remotely?  I already have the address of the Server, and
  785. > figure I need to use AFPCommand, but I don't know how to send the
  786. > proper name/password verification data- or is there just a standard
  787. > call to do all of that for you? (Essentially, I am trying to write
  788. > something that acts as the chooser for you..)
  789.  
  790. There's two ways to do this so that the volume is mounted by the File Manager
  791. (you probably don't want to mount the volume using AFP commands because the
  792. File Manager won't know about the volume if mounted that way).
  793.  
  794. The first method is to use the Alias Manager.  Create a new alias record using
  795. the NewAliasMinimalFromFullPath function.  Then, resolve the alias with the
  796. ResolveAlias function.  The Alias Manager will take care of the user interface
  797. for you.
  798.  
  799. The second way is to use the File Manager's PBVolumeMount function. You'll need
  800. to build an AFP VolumeMountInfo record to pass to PBVolumeMount.  The
  801. BuildAFPVolMountInfo function in the Apple DTS MoreFiles sample code will do
  802. that for you.  MoreFiles also includes a high level versions of the VolumeMount
  803. related calls if you don't like using parameter blocks.
  804.  
  805. - Jim Luther
  806.  
  807.  
  808. ---------------------------
  809.  
  810. >From Frank Price <wprice@jarthur.claremont.edu>
  811. Subject: PPC ThreadManager w-CodeWarrior
  812. Date: 5 Apr 1994 16:38:15 GMT
  813. Organization: Pomona College
  814.  
  815. Has anybody managed to get the ThreadManager 2.0d7 release running native
  816. on the PowerPC using CodeWarrior?  All I get is crashes on NewThread which
  817. somewhat limits what one can do.  Other simple calls like GetCurrentThread
  818. seem to work fine.  Haven't tried this with MPW yet, but I don't imagine it
  819. would be any different (but if it wasn't different, how could they have
  820. released this??)  Compiling the same code for 68k runs fine.  No, I'm not
  821. trying to make preemptive threads, and I believe it would return an error
  822. even if I had.  Also, did anyone notice that the Threads.h header file
  823. doesn't even compile?  An excess comma has to be removed from inside an
  824. enum.  I get the feeling this went out the door a little too quickly.
  825.  
  826. -Frank
  827. _______________________________________________________________________
  828. | Frank Price   |  wprice@jarthur.claremont.edu                        |
  829. |_______________|______________________________________________________|
  830.  
  831. +++++++++++++++++++++++++++
  832.  
  833. >From REDDEN@applelink.apple.com (Kevin Redden)
  834. Date: Tue, 5 Apr 1994 21:07:53 GMT
  835. Organization: Apple Computer
  836.  
  837. In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price
  838. <wprice@jarthur.claremont.edu> wrote:
  839.  
  840. > Has anybody managed to get the ThreadManager 2.0d7 release running native
  841. > on the PowerPC using CodeWarrior?  All I get is crashes on NewThread which
  842. > somewhat limits what one can do.  Other simple calls like GetCurrentThread
  843. > seem to work fine.  Haven't tried this with MPW yet, but I don't imagine it
  844. > would be any different (but if it wasn't different, how could they have
  845. > released this??)  Compiling the same code for 68k runs fine.  No, I'm not
  846. > trying to make preemptive threads, and I believe it would return an error
  847. > even if I had.  Also, did anyone notice that the Threads.h header file
  848. > doesn't even compile?  An excess comma has to be removed from inside an
  849. > enum.  I get the feeling this went out the door a little too quickly.
  850.  
  851. I had some code that I got working with it quite a while ago (I'm not
  852. positive that it was 2.0d7 but I think so because I got the same comma
  853. error), but I never tried it with CodeWarrier, just Apples SDK for PowerPC.
  854.  
  855. The comma compiles straight through with CFront and I believe that PPCC
  856. only flags it when -strict on is specified.  I did bring the comma problem
  857. up with one of the engineers that works on the Threads package but it was
  858. already too late.  Hopefully in the next versionÉ
  859.  
  860. Kevin
  861. Tech Lead, Macintosh On RISC SDK 2.0
  862.  
  863. +++++++++++++++++++++++++++
  864.  
  865. >From bpost@apple.com (Brad Post)
  866. Date: Wed, 6 Apr 1994 01:44:05 GMT
  867. Organization: Apple Computer
  868.  
  869. In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price
  870. <wprice@jarthur.claremont.edu> wrote:
  871. > Has anybody managed to get the ThreadManager 2.0d7 release running native
  872. > on the PowerPC using CodeWarrior?  All I get is crashes on NewThread which
  873. > somewhat limits what one can do.  Other simple calls like GetCurrentThread
  874. > seem to work fine.  Haven't tried this with MPW yet, but I don't imagine it
  875. > would be any different (but if it wasn't different, how could they have
  876. > released this??)  Compiling the same code for 68k runs fine.  No, I'm not
  877. > trying to make preemptive threads, and I believe it would return an error
  878. > even if I had.  Also, did anyone notice that the Threads.h header file
  879. > doesn't even compile?  An excess comma has to be removed from inside an
  880. > enum.  I get the feeling this went out the door a little too quickly.
  881.  
  882.  
  883. Okay this is a simple problem to fix (crashing that is).  The problem is
  884. that you are most likely using the Voodoo Monkey Debugger Init.  It doesn't
  885. know about the native thread manager, so it's trying to do some gross stuff
  886. that it shouldn't be doing.  Remove it and you should work just fine.  As
  887. for the comma, it slipped out, and it should be fixed in the latest/next
  888. release (or it's an exercise for the programmer !-)
  889.  
  890. Brad 'SMMFD' Post
  891.  
  892. +++++++++++++++++++++++++++
  893.  
  894. >From jwbaxter@olympus.net (John W. Baxter)
  895. Date: Tue, 05 Apr 1994 17:46:04 -0700
  896. Organization: Internet for the Olympic Peninsula
  897.  
  898. In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price
  899. <wprice@jarthur.claremont.edu> wrote:
  900.  
  901. > Has anybody managed to get the ThreadManager 2.0d7 release running native
  902. > on the PowerPC using CodeWarrior?  All I get is crashes on NewThread which
  903. > somewhat limits what one can do.
  904.  
  905. You might have better luck with the ThreadManager 2.0 (no qualification)
  906. which appeared on the April Developer CD.  I don't believe this one is the
  907. last word in Thread Managers, either, though.
  908.  
  909. -- 
  910. John Baxter    Port Ludlow, WA, USA  [West shore, Puget Sound]
  911.    jwbaxter@pt.olympus.net
  912.  
  913. +++++++++++++++++++++++++++
  914.  
  915. >From Frank Price <wprice@jarthur.claremont.edu>
  916. Date: 6 Apr 1994 17:04:27 GMT
  917. Organization: Pomona College
  918.  
  919. In article <bpost-050494183834@bsp.apple.com> Brad Post, bpost@apple.com
  920. writes:
  921. >Okay this is a simple problem to fix (crashing that is).  The problem is
  922. >that you are most likely using the Voodoo Monkey Debugger Init.  It doesn't
  923. >know about the native thread manager, so it's trying to do some gross stuff
  924. >that it shouldn't be doing.  Remove it and you should work just fine.  As
  925. >for the comma, it slipped out, and it should be fixed in the latest/next
  926. >release (or it's an exercise for the programmer !-)
  927.  
  928. I wasn't and haven't ever used Voodoo Monkey.  I also took the suggestions
  929. of others to get the 2.0 release off the April CD instead of 2.0d7.  Same
  930. problem.  Compiling the simple NativeThreads app linking with the xcoff
  931. file, it always crashes with an "access fault exception" at NewThread. 
  932. Would appreciate it if someone could try this out to confirm what I'm
  933. saying.  I'm using DR2 of CodeWarrior.  And again, everything still works
  934. fine for the same code in 68k on the same machine.
  935.  
  936. -Frank
  937. _______________________________________________________________________
  938. | Frank Price   |  wprice@jarthur.claremont.edu                        |
  939. |_______________|______________________________________________________|
  940.  
  941. ---------------------------
  942.  
  943. >From piper@char.vnet.net (John Wash)
  944. Subject: RJW: Retrieving application name from OSType Creator
  945. Date: 31 Mar 1994 17:04:19 -0500
  946. Organization: Vnet Internet Access, Inc. - Charlotte, NC. (704) 374-0779
  947.  
  948.  
  949. Hi.  This is done in the Finder, so I'm sure there's a simple way to do 
  950. it.  I have a document reference stored in a database.  I know it's 
  951. four-character Creator.  How do I resolve that Creator into a path to the 
  952. application?
  953.  
  954. I've looked through my old Inside Macs.  It seems to me that it should be 
  955. just a Toolbox call, but I can't seem to find it. 
  956.  
  957. E-mail or followup messages appreciated.
  958.  
  959. Thanks!
  960.  
  961. John Wash
  962. piper@vnet.net
  963.  
  964. -- 
  965. -
  966. John Wash                                               piper@vnet.net
  967. Wee Doggie Musical Instruments                          919-851-4620
  968. "Bagpipes are the missing link between music and noise." --Gordon Mooney
  969.  
  970. +++++++++++++++++++++++++++
  971.  
  972. >From jumplong@aol.com (Jump Long)
  973. Date: 5 Apr 1994 12:34:09 -0400
  974. Organization: America Online, Inc. (1-800-827-6364)
  975.  
  976. In article <2nfhd3$1b3@char.vnet.net>, piper@char.vnet.net (John Wash) writes:
  977.  
  978. > How do I resolve that Creator into a path to the 
  979. > application?
  980.  
  981. I'd start by using the Process Manager to look through the list of open
  982. processes to see if the application is already running.
  983.  
  984. If the process isn't running, then use the Desktop Manager's PBDTGetAPPL
  985. function on the mounted volumes to try to locate the application. You'll want
  986. to start with the volume the file with the creator is on and if you don't find
  987. a match there, go on to the boot volume, local volumes, and then last, remote
  988. volumes.  So, until you find a match, here's the steps you'll need to take:
  989.  
  990. 1) Make sure the volume supports the Desktop Manager using PBHGetVolParms
  991. (check for the bHasDesktopMgr attribute bit).
  992.  
  993. 2) Open the desktop database (i.e., get the dtRefNum needed to make calls to
  994. the Desktop Manager) on that volume using PBDTOpenInform. If PBDTOpenInform
  995. fails with a paramErr, then try again using PBDTGetPath to open the desktop
  996. database.
  997.  
  998. 3) Call PBDTGetAPPL using the creator of the application you want to find.
  999. Start with ioIndex = 0 to get the newest match in the desktop database, check
  1000. to make sure the application match is really there and if not, increment the
  1001. index, call PBDTGetAPPL again to get the next match. If you get to the end of
  1002. the match list on the volume (with an afpItemNotFound error), try the next
  1003. volume.
  1004.  
  1005. OK, so what if you don't find a match using the Desktop Manager, then you'll
  1006. probably want to try any volumes that *don't* support the Desktop Manager (and
  1007. thus, have the old Desktop resource file). There's more than one way to do
  1008. this. You could simply search the volume (using PBCatSearch) for a file with
  1009. the creator and a file type of 'APPL'.  Or, if you really wanted, you could use
  1010. the Desktop file on the disk volume. Since the Finder already has the Desktop
  1011. file open and you won't be able to open it with the Resource Manager, you'll
  1012. need to make a temporary copy of the Desktop file. You can use the FileCopy
  1013. function in DTS's MoreFiles File Manager sample code to make the copy of the
  1014. Desktop file.  Then you can open it up with the Resource Manager and use the
  1015. 'APPL' resourced to attempt to find a matching application.  The Technical Note
  1016. "Resources Contained in the Desktop File" describes the resources you'll find
  1017. in the Desktop file and in particular, the 'APPL' resources.
  1018.  
  1019. So, what else can you do if none of these things finds an application match?
  1020.  
  1021. You could search each mounted volume for for a file with the creator and a file
  1022. type of 'APPL'.  The CreatorTypeFileSearch function in the MoreFiles sample
  1023. uses CatSearch to quickly search a volume for a file specified by creator and
  1024. file type.
  1025.  
  1026. About the only thing you cannot do that the Finder does is look through the
  1027. Finder's open windows for a match.
  1028.  
  1029. - Jim Luther
  1030.  
  1031.  
  1032. ---------------------------
  1033.  
  1034. >From stk@uropax.contrib.de (Stefan Kurth)
  1035. Subject: Range of OSErr's for private use?
  1036. Date: 5 Apr 1994 20:47:50 +0200
  1037. Organization: Contributed Software GbR
  1038.  
  1039. Almost every function that I write returns a value of type OSErr.
  1040. Sometimes it would be desirable to return a private error code of my
  1041. own, rather than one of the Apple ones. Is there a range of values
  1042. that I can safely use for my own #defines, without having to worry
  1043. whether Apple might use them for their system 9.0 implementation of
  1044. the espresso manager or something?
  1045.  
  1046. -Stefan
  1047.  
  1048. _____________________________________________________________________
  1049. Stefan Kurth              Berlin, Germany              stk@contrib.de
  1050.  
  1051. +++++++++++++++++++++++++++
  1052.  
  1053. >From gurgle@netcom.com (Pete Gontier)
  1054. Date: Wed, 6 Apr 1994 19:00:25 GMT
  1055. Organization: cellular
  1056.  
  1057. stk@uropax.contrib.de (Stefan Kurth) writes:
  1058.  
  1059. >Almost every function that I write returns a value of type OSErr.
  1060. >Sometimes it would be desirable to return a private error code of my
  1061. >own, rather than one of the Apple ones. Is there a range of values
  1062. >that I can safely use for my own #defines, without having to worry
  1063. >whether Apple might use them for their system 9.0 implementation of the
  1064. >espresso manager or something?
  1065.  
  1066. I was just thinking about this the other night, and my conclusion
  1067. was both yes and no.
  1068.  
  1069. It seems that the majority of error codes that Apple adds are negative.
  1070. They still have thousands left over, but they like to leave gaps in
  1071. between groups of error codes, so they might use positive codes in the
  1072. not-too-distant future. In fact, they already do use some of the lower
  1073. positive codes (for CTB calls). You could risk using relatively high
  1074. positive codes, but it probably wouldn't work in the long run and it
  1075. wouldn't even be guranateed to work in the short run.
  1076.  
  1077. One alternative I thought of is to simply return a 'long'. Since an
  1078. 'OSErr' is nothing but a signed 16-bit quantity, you could use signed
  1079. values which don't fit in 16 bits for your error codes and return a
  1080. 'long'. When you go to report the error, you could determine if the
  1081. value would have fit into an 'OSErr', and if it would have, that's what
  1082. it is, but if it wouldn't have, it must be one of your custom error
  1083. codes. The only problem with this is that if some of your routines
  1084. return an 'OSErr' and others return a 'CustomErr', C won't help you if
  1085. you forget and assign a 'CustomErr' to an 'OSErr'.
  1086.  
  1087.      (A certain Swede who shall be nameless is likely to pop in here and
  1088.      complain that not only should I really be advocating exceptions
  1089.      instead of error codes but also that Pascal would be much better
  1090.      for this scheme because it wouldn't allow you to screw up assigning
  1091.      the function result. To which I say: yeah, and your mother wears
  1092.      army boots! :-)
  1093.  
  1094. Of course, this is not what I personally do. Each of my modules has a
  1095. unique 8-bit "location code", and each module's functions which can
  1096. produce errors produce a 16-bit struct (fits nicely in a register)
  1097. which also contains a non-unique error code. Put the two codes together
  1098. and you have a description of which module caused the error and a a
  1099. description of what the error was which does not rely on 'OSErr'.
  1100. -- 
  1101.  Pete Gontier, CTO, Integer Poet Software; gurgle@netcom.com
  1102.  
  1103. ---------------------------
  1104.  
  1105. >From guyyalif@tucson.Princeton.EDU (Guy Udassin Yalif)
  1106. Subject: Simple Q: Assigning char * to char []. How?
  1107. Date: Mon, 4 Apr 1994 21:27:46 GMT
  1108. Organization: Princeton University
  1109.  
  1110. This seems ridiculous: You should be able to assign a char * to 
  1111. an array of characters.  If you declare char a[10], a is a pointer
  1112. to the first of a contiguous group of 10 characters.  Yet when I try
  1113. this on THINK C 6.0.1, it tells me I cannot assign to an array.  If
  1114. I try to get around this with an assignment to &a[0], it tells
  1115. me that an lvalue is required.  This is an error I have gotten 
  1116. many times, and I do not know how to get around it.  ANY help would
  1117. be greatly appreciated!! Thanks for the time.  Guy
  1118. guyyalif@phoenix.princeton.edu
  1119.  
  1120. +++++++++++++++++++++++++++
  1121.  
  1122. >From zstern@adobe.com (Zalman Stern)
  1123. Date: Tue, 5 Apr 1994 06:32:24 GMT
  1124. Organization: Adobe Systems Incorporated
  1125.  
  1126. Guy Udassin Yalif writes
  1127. > This seems ridiculous: You should be able to assign a char * to 
  1128. > an array of characters.  If you declare char a[10], a is a pointer
  1129. > to the first of a contiguous group of 10 characters.
  1130.  
  1131. No, a represents an absolute address of ten characters of storage. There is  
  1132. no storage allocated for a pointer (e.g. 4 bytes holding an address) which  
  1133. points to the beginning of that ten byte array. Another way to put this is  
  1134. that the declarations "extern char a[]" and "extern char *a" are very  
  1135. different. The best way to see this is to look at the assembly code  
  1136. generated for the following function:
  1137.  
  1138. extern char an_array[];
  1139. extern char *a_pointer;
  1140.  
  1141. int foo(void)
  1142. {
  1143.     int return_value;
  1144.  
  1145.     return_value = an_array[42];
  1146.     return_value += a_pointer[42];
  1147.  
  1148.     return return_value;
  1149. }
  1150.  
  1151. > Yet when I try
  1152. > this on THINK C 6.0.1, it tells me I cannot assign to an array.  If
  1153. > I try to get around this with an assignment to &a[0], it tells
  1154. > me that an lvalue is required.  This is an error I have gotten 
  1155. > many times, and I do not know how to get around it.  ANY help would
  1156. > be greatly appreciated!! Thanks for the time.  Guy
  1157.  
  1158. The C language specification says that array values are automatically  
  1159. converted to pointer values in most circumstances. It does not say they are  
  1160. the same thing. Think-C is trying to tell you that you do not understand the  
  1161. language. A good reading of the ANSI-C standard or other rigorous C  
  1162. documentation might be in order.
  1163. --
  1164. Zalman Stern           zalman@adobe.com            (415) 962 3824
  1165. Adobe Systems, 1585 Charleston Rd., POB 7900, Mountain View, CA 94039-7900
  1166. "Do right, and risk consequences." Motto of Sam Houston (via Molly Ivins)
  1167.  
  1168. +++++++++++++++++++++++++++
  1169.  
  1170. >From d88-jwa@mumrik.nada.kth.se (Jon Wätte)
  1171. Date: 5 Apr 1994 08:00:58 GMT
  1172. Organization: The Royal Institute of Technology
  1173.  
  1174. In <1994Apr4.212746.24171@Princeton.EDU> guyyalif@tucson.Princeton.EDU (Guy Udassin Yalif) writes:
  1175.  
  1176. >This seems ridiculous: You should be able to assign a char * to 
  1177. >an array of characters.  If you declare char a[10], a is a pointer
  1178.  
  1179. No, you should not. It's right there in K&R 2nd ed (and, indeed,
  1180. 1st ed as well)
  1181.  
  1182. That's because the array is a CONSTANT pointer to a slab of memory
  1183. that lives on the stack or in global space. You can't just move that
  1184. slab of memory; all you can do is copy stuff into or out of the
  1185. memory the array is "pointing to".
  1186.  
  1187. >me that an lvalue is required.  This is an error I have gotten 
  1188. >many times, and I do not know how to get around it.  ANY help would
  1189.  
  1190. You can't. If you want to shove stuff into the actual array memory,
  1191. you should use strcpy() or memcpy() or possibly BlockMove(). If you
  1192. want a variable that can point at different arrays, you should use
  1193. a pointer variable and initialize it first.
  1194. -- 
  1195.  -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
  1196.  
  1197.    What we need is a good GNU [...] licence manager implementation.
  1198.                      -- Raphael Manfredi
  1199.  
  1200. ---------------------------
  1201.  
  1202. >From potterf@tartarus.uwa.edu.au (Felix Potter)
  1203. Subject: [Q] Validity of a memory address
  1204. Date: 28 Mar 1994 06:54:22 GMT
  1205. Organization: The University of Western Australia
  1206.  
  1207. How does one check that a pointer is valid?  (Without dereferencing it and
  1208. possibly crashing the machine.)  At the moment my definition for a pointer
  1209. that is at least _possibly_ OK is:
  1210.     not null (ie. not equal to 0), and
  1211.     even (ie. not divisble by 2), and
  1212.     > ApplZone (low memory global), and
  1213.     < ApplLimit (low memory global)
  1214. So if my pointer fails one of these conditions, then I know straight away
  1215. that something has gone wrong.  Does anyone have any comments on either how
  1216. reasonable or, on the other hand, how totally stupid the above description is?
  1217. Any suggestions for better ways of going about it?
  1218.  
  1219. The reason I want to be able to check _quickly_ whether a pointer is valid
  1220. or not is that I am writing a few little 'wrapper' macros/functions to
  1221. go around the standard C malloc/calloc/realloc/free functions.  I realise that
  1222. just about every man and his dog has done this before me, but hey, I'm
  1223. having fun :)  One of the things I would like to be able to do is detect
  1224. heap corruption, and corruption of my record keeping information in
  1225. particular, and so I'd like to be able to tell if dereferencing a pointer
  1226. is going to crash my code or not before I do it, in a few strategic places.
  1227. Hence my above query.
  1228.  
  1229. Also, I'm going to be asking in come more general-purpose newsgroups, but
  1230. does anyone have any ideas about how to check pointers on other systems,
  1231. DOS and UNIX in particular?
  1232.  
  1233. Thanks for any help (or even idle flames, if I'm being particularly stupid :)
  1234.  
  1235. --
  1236. ____________________________________________________________________________
  1237.  Felix Potter                                   potterf@lethe.uwa.edu.au
  1238.                                                 potterf@tartarus.uwa.edu.au
  1239.  University of Western Australia, Perth.        potter_f@cs.uwa.edu.au
  1240.  
  1241. +++++++++++++++++++++++++++
  1242.  
  1243. >From potterf@tartarus.uwa.edu.au (Felix Potter)
  1244. Date: 28 Mar 1994 06:58:21 GMT
  1245. Organization: The University of Western Australia
  1246.  
  1247. I (potterf@tartarus.uwa.edu.au), in a fit of stupidity, wrote:
  1248. > How does one check that a pointer is valid?  (Without dereferencing it and
  1249. > possibly crashing the machine.)  At the moment my definition for a pointer
  1250. > that is at least _possibly_ OK is:
  1251. >     not null (ie. not equal to 0), and
  1252. >     even (ie. not divisble by 2), and
  1253.       ^^^^      ^^^^^^^^^^^^^^^^^
  1254.  
  1255. Oops *blush* :)
  1256.  
  1257. Obviously I mean "divisible by 2."
  1258.  
  1259. --
  1260. ____________________________________________________________________________
  1261.  Felix Potter                                   potterf@lethe.uwa.edu.au
  1262.                                                 potterf@tartarus.uwa.edu.au
  1263.  University of Western Australia, Perth.        potter_f@cs.uwa.edu.au
  1264.  
  1265. +++++++++++++++++++++++++++
  1266.  
  1267. >From Cameron Esfahani <dirty@guest.apple.com>
  1268. Date: Mon, 4 Apr 1994 04:42:50 GMT
  1269. Organization: Apple Computer, Inc.
  1270.  
  1271. In article <2n5uuu$ekq@styx.uwa.edu.au> Felix Potter,
  1272. potterf@tartarus.uwa.edu.au writes:
  1273. > How does one check that a pointer is valid?  (Without dereferencing it and
  1274. > possibly crashing the machine.)  At the moment my definition for a pointer
  1275. > that is at least _possibly_ OK is:
  1276. >     not null (ie. not equal to 0), and
  1277. >     even (ie. not divisble by 2), and
  1278. >     > ApplZone (low memory global), and
  1279. >     < ApplLimit (low memory global)
  1280. > So if my pointer fails one of these conditions, then I know straight away
  1281. > that something has gone wrong.  Does anyone have any comments on either how
  1282. > reasonable or, on the other hand, how totally stupid the above description
  1283. is?
  1284. > Any suggestions for better ways of going about it?
  1285. > The reason I want to be able to check _quickly_ whether a pointer is valid
  1286. > or not is that I am writing a few little 'wrapper' macros/functions to
  1287. > go around the standard C malloc/calloc/realloc/free functions.  I realise
  1288. that
  1289. > just about every man and his dog has done this before me, but hey, I'm
  1290. > having fun :)  One of the things I would like to be able to do is detect
  1291. > heap corruption, and corruption of my record keeping information in
  1292. > particular, and so I'd like to be able to tell if dereferencing a pointer
  1293. > is going to crash my code or not before I do it, in a few strategic places.
  1294. > Hence my above query.
  1295. > Also, I'm going to be asking in come more general-purpose newsgroups, but
  1296. > does anyone have any ideas about how to check pointers on other systems,
  1297. > DOS and UNIX in particular?
  1298. > Thanks for any help (or even idle flames, if I'm being particularly stupid :)
  1299.  
  1300. Well, try installing your own Bus Error Handler and dereference
  1301. the pointer.  If you get called in your Bus Error Handler, then it
  1302. is not a valid pointer.  If you don't, it's valid....
  1303.  
  1304. Cameron Esfahani
  1305. dirty@apple.com
  1306.  
  1307. +++++++++++++++++++++++++++
  1308.  
  1309. >From ari@world.std.com (Ari I Halberstadt)
  1310. Date: Mon, 4 Apr 1994 06:26:22 GMT
  1311. Organization: The World Public Access UNIX, Brookline, MA
  1312.  
  1313. In article <2n5uuu$ekq@styx.uwa.edu.au>,
  1314. Felix Potter <potterf@tartarus.uwa.edu.au> wrote:
  1315. >How does one check that a pointer is valid?  (Without dereferencing it and
  1316. >possibly crashing the machine.)  At the moment my definition for a pointer
  1317. >that is at least _possibly_ OK is:
  1318. >    not null (ie. not equal to 0), and
  1319. >    even (ie. not divisble by 2), and
  1320. >    > ApplZone (low memory global), and
  1321. >    < ApplLimit (low memory global)
  1322. >So if my pointer fails one of these conditions, then I know straight away
  1323. >that something has gone wrong.  Does anyone have any comments on either how
  1324. >reasonable or, on the other hand, how totally stupid the above description is?
  1325. >Any suggestions for better ways of going about it?
  1326.  
  1327. Those are most of the tests you'd ever need. If you get a crash from
  1328. dereferencing a pointer after doing those checks then I'd be pretty
  1329. surprised. If you didn't mind the speed hit, you could look for the
  1330. pointer in some private table of valid pointers, using some sort of
  1331. binary tree, for instance. What these tests don't tell you, however,
  1332. is whether the contents of the pointer are valid.
  1333.  
  1334. What I've done in my applications is create a header that is placed at
  1335. the start of every pointer allocated. The header contains the size of
  1336. the pointer and a 4-byte signature code. A unique signature code is
  1337. used for every type of object I allocate. Then I do something like
  1338. this:
  1339.  
  1340. ObjectPtr NewObject(...) {
  1341.   ObjectPtr object = NewObjectPtr(sizeof(ObjectType), 'objp');
  1342.   ...
  1343.   assert(ValidObject(object));
  1344.   return(object);
  1345. }
  1346.  
  1347. Boolean ValidObject(ObjectPtr object) {
  1348.   if (! ValidObjectPtr(object, sizeof(ObjectType), 'objp')) return(false);
  1349.   ... more tests to check relationships among members of the object ...
  1350. }
  1351.  
  1352. void DoSomethingToObject(ObjectPtr object) {
  1353.   assert(ValidObject(object));
  1354.   ... use object ...
  1355.   assert(ValidObject(object));
  1356. }
  1357.  
  1358. The function ValidObjectPtr compares the size and ID code passed to it
  1359. as parameters with the values stored in the pointer's header. If they
  1360. differ, then the pointer is deemed invalid and false is returned. The
  1361. function also checks that the pointer's header and the end of the
  1362. pointer are within the application's heap zone.
  1363.  
  1364. As a further enhancement, you could store a trailer at the end of each
  1365. pointer. The trailer would contain the same 4-byte id code, and would
  1366. help catch errors that resulted from overwriting the end of the
  1367. pointer.
  1368.  
  1369. Also, when you allocate a pointer, fill it with some random (or not so
  1370. random) garbage. Something like 0xff works pretty well and is easy to
  1371. spot with a debugger. Using an odd value like 0xff is also good since
  1372. any members of the object that are pointers will be detected as
  1373. illegal pointers (since they'll be odd integers). When you dispose of
  1374. the pointer, again fill it with 0xff, since this will ensure that you
  1375. won't be able to use its contents without immediate errors.
  1376. Alternatively, you could zero the pointer when you allocate it, thus
  1377. removing the need to initialize members to a default value. However,
  1378. you should still fill the pointer with invalid data when it is
  1379. disposed of. My personal preference is to zero program objects but to
  1380. fill data pointers with 0xff bits. I disable the filling of memory
  1381. with 0xff bits for greater efficiency in the final application
  1382.  
  1383. If you were really paranoid, you could checksum the contents of the
  1384. pointer. For instance, instead of just calling ValidObject, you could
  1385. do something like:
  1386.  
  1387.   CheckInObject(object);
  1388.   ...
  1389.   CheckOutObject(object);
  1390.  
  1391. CheckInObject would calculate a checksum for the object and compare it
  1392. with the checksum saved in the pointer's header. If the checksums
  1393. differ, CheckInObject would fail (e.g., raise an exception). Then, it
  1394. would call ValidObject, and finally it would increment a counter to
  1395. indicate that the object had been checksummed and is in use. A value
  1396. greater than zero for the counter would prevent further calls to
  1397. CheckInObject from calculating a checksum or calling ValidObject.
  1398. CheckOutObject would decrement the counter each time it is called.
  1399. When the matching call to CheckOutObject is made (the counter is zero)
  1400. then a new checksum would be calculated for the object and the
  1401. checksum would be stored in the pointer's header. This should be
  1402. reasonably efficient and quite robust. You could make CheckInObject
  1403. and CheckOutObject macros that you could undefine when debug code was
  1404. disabled, or could change the macros so that they didn't do the
  1405. checksum operation in the final product. I haven't used this method
  1406. yet in my own applications, but I'm thinking of adding it.
  1407.  
  1408. >
  1409. >The reason I want to be able to check _quickly_ whether a pointer is valid
  1410. >or not is that I am writing a few little 'wrapper' macros/functions to
  1411. >go around the standard C malloc/calloc/realloc/free functions.  I realise that
  1412. >just about every man and his dog has done this before me, but hey, I'm
  1413. >having fun :)  One of the things I would like to be able to do is detect
  1414. >heap corruption, and corruption of my record keeping information in
  1415. >particular, and so I'd like to be able to tell if dereferencing a pointer
  1416. >is going to crash my code or not before I do it, in a few strategic places.
  1417. >Hence my above query.
  1418.  
  1419. To check the heap, you can just use MacsBug or TMON with heap check
  1420. enabled.  It works pretty well for most things. With TMON, one problem
  1421. is that by the time the heap is corrupted you can't figure out where
  1422. it failed in your code since all of the function labels are gone (it's
  1423. kind of a pain to get around this problem).
  1424.  
  1425. I like to validate memory on several different levels. The most
  1426. secure, but slowest, level is used during development. Less checks are
  1427. done in a beta level, and most (or all) checks are disabled in a
  1428. release version. However, lately, my memory checks have been fairly
  1429. fast (they used to be really slow), so I'm thinking of leaving at
  1430. least some of them in the release level.
  1431.  
  1432. Just checking the validity of pointers before calling memory
  1433. allocation and disposal routines is better than nothing, but overall
  1434. is not very secure. A pointer can easily become corrupted long before
  1435. free is ever called on it. You can also do a lot of extra verification
  1436. if you provide type information (like a four-byte code) in your code.
  1437. If you get fancy, you can even check the logical relationships among
  1438. the members of your objects. Checking logical relationships helps
  1439. catch additional programmatic errors.
  1440.  
  1441. >Also, I'm going to be asking in come more general-purpose newsgroups, but
  1442. >does anyone have any ideas about how to check pointers on other systems,
  1443. >DOS and UNIX in particular?
  1444.  
  1445. All of the checks I described above can be used on Unix systems. You
  1446. might have trouble finding something equivalent to ApplZone/ApplLimit
  1447. on Unix, but there's probably some equivalent, even if it's not
  1448. totally portable. The checks should probably also work with DOS
  1449. systems.  The interpretation of multiple byte character constants is
  1450. not defined by the language, so things like 'objp' may have to be
  1451. modified (e.g., use defines in some common memory header, don't
  1452. scatter the constants all over the place).
  1453.  
  1454. -- 
  1455. Ari Halberstadt    ari@world.std.com     #include <std/disclaimer.h>
  1456. "These beetles were long considered to be very rare because very few
  1457. entomologists look for beetles in the mountains, in winter, at night,
  1458. during snow storms." -- Purves W. K., et al, "Life: The Science of
  1459.  
  1460. +++++++++++++++++++++++++++
  1461.  
  1462. >From Alexander M. Rosenberg <alexr@apple.com>
  1463. Date: Mon, 4 Apr 1994 12:39:22 GMT
  1464. Organization: Hackers Anonymous
  1465.  
  1466. In article <1994Apr4.044250.27756@gallant.apple.com> Cameron Esfahani,
  1467. dirty@guest.apple.com writes:
  1468. > Well, try installing your own Bus Error Handler and dereference
  1469. > the pointer.  If you get called in your Bus Error Handler, then it
  1470. > is not a valid pointer.  If you don't, it's valid....
  1471.  
  1472. Trouble-maker.
  1473. - -------------------------------------------------------------------------
  1474. -  Alexander M. Rosenberg  - INTERNET: alexr@apple.com      - Yoyodyne    -
  1475. -  330 Waverley St., Apt B - UUCP:ucbvax!apple!alexr        - Propulsion  -
  1476. -  Palo Alto, CA 94301     -                                - Systems     -
  1477. -  (415) 329-8463          - Nobody is my employer so       - :-)         -
  1478. -                          - nobody cares what I say.       -             -
  1479.  
  1480. +++++++++++++++++++++++++++
  1481.  
  1482. >From jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne)
  1483. Date: 5 Apr 94 05:34:57 GMT
  1484. Organization: University of Illinois at Urbana
  1485.  
  1486. ari@world.std.com (Ari I Halberstadt) writes:
  1487.  
  1488. >What I've done in my applications... 
  1489.  
  1490. Ari offers some good suggestions.  I once saw most of his suggestions
  1491. implemented in a library that was published in MacTech (MacTutor?) a while
  1492. back.  I can't remember the name of the article, but I remember the library
  1493. functioned on the principle of wrapping accesses to your data with MMUse and
  1494. MMUnuse.  The idea being that you had to call MMUse to be able to use your
  1495. data and must call MMUnuse as soon as you were done with it at that point.
  1496. This allowed for all kinds of nifty things the library could do behind your
  1497. back, like checksumming, checking for leaks, and even some primitive virtual
  1498. memory techniques.  If I could remember the names of the authors, I'd cite
  1499. them for you.
  1500.  
  1501. (Was it 'MemMan'?)
  1502. -- 
  1503. Jim Browne                                             | jbrowne@ncsa.uiuc.edu |
  1504. Head NCSA Mac Telnet Hacker, SDG System Administrator  | (217) 244-7798        |
  1505. <a href="http://www.ncsa.uiuc.edu/SDG/People/jbrowne/jbrowne.html">Click me</a>
  1506.                     "Not me, not yet, not that bad."
  1507.  
  1508. +++++++++++++++++++++++++++
  1509.  
  1510. >From jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne)
  1511. Date: 5 Apr 94 07:28:00 GMT
  1512. Organization: University of Illinois at Urbana
  1513.  
  1514. jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne) writes:
  1515.  
  1516. >ari@world.std.com (Ari I Halberstadt) writes:
  1517.  
  1518. >>What I've done in my applications... 
  1519.  
  1520. >Ari offers some good suggestions.  I once saw most of his suggestions
  1521. >implemented in a library that was published in MacTech (MacTutor?) a while
  1522. >back.  I can't remember the name of the article, but I remember the library
  1523. >functioned on the principle of wrapping accesses to your data with MMUse and
  1524. >MMUnuse.  The idea being that you had to call MMUse to be able to use your
  1525. >data and must call MMUnuse as soon as you were done with it at that point.
  1526. >This allowed for all kinds of nifty things the library could do behind your
  1527. >back, like checksumming, checking for leaks, and even some primitive virtual
  1528. >memory techniques.  If I could remember the names of the authors, I'd cite
  1529. >them for you.
  1530.  
  1531. Well, I've gone and looked up the article.  Thanks to those great people at
  1532. MacTech, I was able to grep the text index of articles for MacTech vols. 1-8.
  1533.  
  1534. Here's the reference:
  1535.  
  1536. "A Memory Manager for the Rest of US." by Jordan Zimmerman.  Vol. 7 No. 9 Pg. 40
  1537.  
  1538.  
  1539. -- 
  1540. Jim Browne                                             | jbrowne@ncsa.uiuc.edu |
  1541. Head NCSA Mac Telnet Hacker, SDG System Administrator  | (217) 244-7798        |
  1542. <a href="http://www.ncsa.uiuc.edu/SDG/People/jbrowne/jbrowne.html">Click me</a>
  1543. --"It's really weird... kind of like how Telnet is programmed." - Q. Koziol --
  1544.  
  1545. ---------------------------
  1546.  
  1547. >From Ben J Fry <bf2c+@andrew.cmu.edu>
  1548. Subject: textedit bounds
  1549. Date: Tue,  5 Apr 1994 21:15:13 -0400
  1550. Organization: Freshman, Design, Carnegie Mellon, Pittsburgh, PA
  1551.  
  1552. does anyone know how to figure out the real boundaries for a styled
  1553. textedit field? that is, the natural boundary rectangle that the text
  1554. would fit in...
  1555.  
  1556. any help would be really appreciated.. i've nearly worn out my think
  1557. reference in trying to look for this... (if that's possible...)
  1558.  
  1559.  
  1560. ben
  1561.  
  1562. +++++++++++++++++++++++++++
  1563.  
  1564. >From ari@world.std.com (Ari I Halberstadt)
  1565. Date: Wed, 6 Apr 1994 21:27:41 GMT
  1566. Organization: The World Public Access UNIX, Brookline, MA
  1567.  
  1568. In article <MhcUoV200iV8IC9nE_@andrew.cmu.edu>,
  1569. Ben J Fry  <bf2c+@andrew.cmu.edu> wrote:
  1570. >does anyone know how to figure out the real boundaries for a styled
  1571. >textedit field? that is, the natural boundary rectangle that the text
  1572. >would fit in...
  1573. >
  1574. >any help would be really appreciated.. i've nearly worn out my think
  1575. >reference in trying to look for this... (if that's possible...)
  1576. >
  1577. >
  1578. >ben
  1579.  
  1580.  
  1581. Assuming you have word wrap turned on, you can find the width of the
  1582. text from the width of the destination rectangle. You can get the
  1583. height of the text with TEGetHeight. If you don't have word wrap
  1584. turned on, then you can either assume some maximum width, say 72
  1585. inches (5184 pixels). This is a large enough value to ensure that the
  1586. user can view most text, without making the horizontal scroll bar
  1587. as useless as a value of 32767 would. If you really want to be
  1588. accurate, then you you can calculate the width of the widest line in
  1589. the text. Here's some code to do this for both styled and unstyled
  1590. text. It knows way too much about TextEdit internals, but hey, it
  1591. works :-)
  1592.  
  1593. A few utility functions:
  1594.  
  1595. typedef unsigned long TicksType;
  1596. typedef SignedByte HandleStateType;
  1597.  
  1598. HandleStateType HandleLock(void *h)
  1599. {
  1600.   HandleStateType state;
  1601.  
  1602.   state = HGetState(h);
  1603.   HLock(h);
  1604.   return(state);
  1605. }
  1606.  
  1607. void HandleStateSet(void *h, HandleStateType state)
  1608. {
  1609.   HSetState(h, state);
  1610. }
  1611.  
  1612. // word wrap macros
  1613. #define TEWrap(te)          ((**(te)).crOnly >= 0)
  1614. #define TEWrapSet(wrap, te) ((void) ((**(te)).crOnly = ((wrap) ? 1 : -1)))
  1615.  
  1616. static Boolean TEOldStyle(TEHandle te)
  1617. {
  1618.     return((**te).txSize != -1);
  1619. }
  1620.  
  1621. /* Calculate the width of the widest line in the line range. If the
  1622.    operation takes longer than 'timeout' ticks to compute, then the
  1623.    last line reached is returned in 'finalLine', and the result of
  1624.    the function is the width of the widest line between 'firstLine'
  1625.    and 'finalLine'. Otherwise (i.e., no timeout), the result of the
  1626.    function is the width of the widest line and 'finalLine' is equal
  1627.    to 'lastLine'.
  1628.    
  1629.    The time out is provided since calculating the widths of the lines--
  1630.    especially for long styled text documents--can take quite a while, and
  1631.    doing so every time the document changes could be prohibitively slow.
  1632.    Instead, if 'finalLine' is less than 'lastLine', then after processing some
  1633.    events, the application can continue to call this function, passing
  1634.    the value of 'finalLine' as the 'firstLine' parameter, until 'finalLine'
  1635.    is equal to 'lastLine', at which point the maximum of the values returned
  1636.    by the successive calls to this function will be the width of the widest
  1637.    line in the original line range. */
  1638. static short TEWidthUnstyled(short firstLine, short lastLine,
  1639.    TicksType timeout, long *finalLine, TEHandle te)
  1640. {
  1641.    HandleStateType   svTextHandleState;    /* saved state of handle to text */
  1642.    GrafPtr           svPort;               /* saved graf port */
  1643.    Ptr               textPtr;              /* pointer to text */
  1644.    short             textWidth;            /* width of text */
  1645.    short             lineIndex;            /* current line number */
  1646.    short             lineLongest;          /* length of longest line */
  1647.    short             lineStart;            /* first character of line */
  1648.    short             lineEnd;              /* last character of line */
  1649.    long              startTicks            /* time when we started */
  1650.    short             txFont, txSize, txFace;   /* saved text state */
  1651.       
  1652.    require(TEOldStyle(te));
  1653.    
  1654.    /* quick out */
  1655.    if ((**te).nLines == 0) return(0);
  1656.       
  1657.    /* keep track of elapsed time */
  1658.    startTicks = TickCount();
  1659.    
  1660.    /* find longest line */
  1661.    lineStart = lineEnd = lineLongest = 0;
  1662.    for (lineIndex = firstLine; lineIndex < lastLine; lineIndex++) {
  1663.  
  1664.       /* remember length of longest line encountered so far */
  1665.       if (lineLongest < (**te).lineStarts[lineIndex + 1] - (**te).lineStarts[lineIndex]) {
  1666.          lineStart = (**te).lineStarts[lineIndex];
  1667.          lineEnd = (**te).lineStarts[lineIndex + 1];
  1668.          lineLongest = lineEnd - lineStart;
  1669.       }
  1670.  
  1671.       /* stop if took too long */
  1672.       if (TickCount() - startTicks > timeout)
  1673.          break;
  1674.    }
  1675.    
  1676.    /* calculate width of longest line */
  1677.    GetPort(&svPort);
  1678.    SetPort((**te).inPort);
  1679.    txFont = (**te).inPort->txFont;
  1680.    txSize = (**te).inPort->txSize;
  1681.    txFace = (**te).inPort->txFace;
  1682.    TextFont((**te).txFont);
  1683.    TextSize((**te).txSize);
  1684.    TextFace((**te).txFace);
  1685.    svTextHandleState = HandleLock((**te).hText);
  1686.    textPtr = *(**te).hText;
  1687.    textWidth = TextWidth(textPtr, lineStart, lineEnd - lineStart);
  1688.    HandleStateSet((**te).hText, svTextHandleState);
  1689.    TextFont(txFont);
  1690.    TextSize(txSize);
  1691.    TextFace(txFace);
  1692.    SetPort(svPort);
  1693.  
  1694.    *finalLine = lineIndex;
  1695.    return(textWidth);
  1696. }
  1697.  
  1698. /* see description of TEWidthUnstyled */
  1699. static short TEWidthStyled(short firstLine, short lastLine, TicksType timeout,
  1700.    long *finalLine, TEHandle te)
  1701. {
  1702.    HandleStateType   svTextHandleState;      /* saved state of handle to text */
  1703.    HandleStateType   svStyleHandleState;     /* saved state of handle to style record */
  1704.    HandleStateType   svStyleTableState;      /* saved state of handle to style table */
  1705.    GrafPtr           svPort;                 /* saved graf port */
  1706.    TEStylePtr        stylePtr;               /* text's style record */
  1707.    STPtr             styleTable;             /* text's style table */
  1708.    StyleRun         *runPtr;                 /* style runs array */
  1709.    short             runStart;               /* start of next style run */
  1710.    Ptr               textPtr;                /* pointer to text */
  1711.    short             textLength;             /* length of text run */
  1712.    short             textWidth;              /* width of text */
  1713.    short             lineWidth;              /* width of current line */
  1714.    short             lineIndex;              /* current line number */
  1715.    short             lineStart;              /* first character of line */
  1716.    short             lineEnd;                /* last character of line */
  1717.    long              startTicks;             /* time when we started */
  1718.    short             txFont, txSize, txFace; /* saved text state */
  1719.    
  1720.    require(! TEOldStyle(te));
  1721.    
  1722.    /* quick out */
  1723.    if ((**te).nLines == 0) return(0);
  1724.  
  1725.    /* keep track of elapsed time */
  1726.    startTicks = TickCount();
  1727.    
  1728.    /* setup port */   
  1729.    GetPort(&svPort);
  1730.    SetPort((**te).inPort);
  1731.    txFont = (**te).inPort->txFont;
  1732.    txSize = (**te).inPort->txSize;
  1733.    txFace = (**te).inPort->txFace;
  1734.    
  1735.    /* lock and dereference handles */
  1736.    svTextHandleState = HandleLock((**te).hText);
  1737.    textPtr = *(**te).hText;
  1738.    svStyleHandleState = HandleLock(GetStylHandle(te));
  1739.    stylePtr = *GetStylHandle(te);
  1740.    svStyleTableState = HandleLock(stylePtr->styleTab);
  1741.    styleTable = *stylePtr->styleTab;
  1742.    
  1743.    /* initialize loop */
  1744.    textWidth = 0;
  1745.    runPtr = stylePtr->runs;
  1746.    runStart = runPtr[1].startChar;
  1747.    TextFont(styleTable[runPtr->styleIndex].stFont);
  1748.    TextFace(styleTable[runPtr->styleIndex].stFace);
  1749.    TextSize(styleTable[runPtr->styleIndex].stSize);
  1750.    
  1751.    /* calculate widths of all lines */
  1752.    for (lineIndex = firstLine; lineIndex < lastLine; lineIndex++) {
  1753.    
  1754.       /* calculate width of line */
  1755.       lineWidth = 0;
  1756.       lineStart = (**te).lineStarts[lineIndex];
  1757.       lineEnd = (**te).lineStarts[lineIndex + 1];
  1758.       while (lineStart < lineEnd) {
  1759.          if (lineStart == runStart) {
  1760.             /* use next style run (assumes run array is sorted by startChar) */
  1761.             runPtr++;
  1762.             runStart = runPtr[1].startChar;
  1763.             check(runPtr->startChar == lineStart);
  1764.             TextFont(styleTable[runPtr->styleIndex].stFont);
  1765.             TextFace(styleTable[runPtr->styleIndex].stFace);
  1766.             TextSize(styleTable[runPtr->styleIndex].stSize);
  1767.          }
  1768.          /* calculate width of style run */
  1769.          check(lineStart < runStart);
  1770.          textLength = min(lineEnd - lineStart, runStart - lineStart);
  1771.          check(textLength >= 1);
  1772.          lineWidth += TextWidth(textPtr, lineStart, textLength);
  1773.          lineStart += textLength;
  1774.       }
  1775.       textWidth = max(textWidth, lineWidth);
  1776.       
  1777.       /* stop if took too long */
  1778.       if (TickCount() - startTicks > timeout)
  1779.          break;
  1780.    }
  1781.  
  1782.    /* restore saved state */
  1783.    HandleStateSet(RecoverHandle((Ptr) styleTable), svStyleTableState);
  1784.    HandleStateSet(RecoverHandle((Ptr) stylePtr), svStyleHandleState);
  1785.    HandleStateSet(RecoverHandle((Ptr) textPtr), svTextHandleState);
  1786.    TextFont(txFont);
  1787.    TextSize(txSize);
  1788.    TextFace(txFace);
  1789.    SetPort(svPort);
  1790.    
  1791.    *finalLine = lineIndex;
  1792.    return(textWidth);
  1793. }
  1794.  
  1795. /* see description of TEWidthUnstyled */
  1796. short TEWidthTimeout(short start, short end,
  1797.    TicksType timeout, long *final, TEHandle te)
  1798. {
  1799.    return(TEOldStyle(te) ? TEWidthUnstyled(start, end, timeout, final, te) :
  1800.                            TEWidthStyled(start, end, timeout, final, te));
  1801. }
  1802.  
  1803. /* calculate the width of the widest line in the line range */
  1804. short TEWidth(short start, short end, TEHandle te)
  1805. {
  1806.    return(TEWidthTimeout(start, end, LONG_MAX, 0, te));
  1807. }
  1808. -- 
  1809. Ari Halberstadt    ari@world.std.com     #include <std/disclaimer.h>
  1810. "These beetles were long considered to be very rare because very few
  1811. entomologists look for beetles in the mountains, in winter, at night,
  1812. during snow storms." -- Purves W. K., et al, "Life: The Science of
  1813.  
  1814. ---------------------------
  1815.  
  1816. End of C.S.M.P. Digest
  1817. **********************
  1818.  
  1819.  
  1820.  
  1821.